package com.hangsu.train.hl7;

import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.model.Varies;
import ca.uhn.hl7v2.model.v26.datatype.*;
import ca.uhn.hl7v2.model.Type;
import ca.uhn.hl7v2.model.v26.group.ORU_R01_OBSERVATION;
import ca.uhn.hl7v2.model.v26.message.ORU_R01;
import ca.uhn.hl7v2.model.v26.segment.MSH;
import ca.uhn.hl7v2.model.v26.segment.OBX;
import ca.uhn.hl7v2.model.v26.segment.PID;
import ca.uhn.hl7v2.protocol.ReceivingApplication;
import ca.uhn.hl7v2.protocol.ReceivingApplicationException;
import ca.uhn.hl7v2.util.Terser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hangsu.train.heatbeat.Server;
import com.hangsu.train.netty.ClientHolder;
import com.hangsu.train.netty.transfer.Context;
import com.hangsu.train.netty.transfer.ECG;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class MyReceivingApplication implements ReceivingApplication {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    long delay = TimeUnit.SECONDS.toNanos(1) / 500;

    @Override
    public Message processMessage(Message message, Map map) throws ReceivingApplicationException, HL7Exception {
        String result = message.printStructure();
//        System.out.println(System.currentTimeMillis());

        ORU_R01 oruMessage = (ORU_R01) message;

        String version = oruMessage.getVersion();


        // 获取 MSH 段
        MSH msh = oruMessage.getMSH();
        String[] msh3Arr= msh.getMsh3_SendingApplication().encode().split("\\^");
        if(msh3Arr.length>2){
            String serialNumber=msh3Arr[1];
            Server.getInstance().ping(serialNumber);
        }

        // 获取 PID 段
        PID pid = oruMessage.getPATIENT_RESULT().getPATIENT().getPID();
        // 提取病历号 (Patient Identifier)
        String medicalRecordNumber = pid.getPatientIdentifierList(0).getIDNumber().getValue();

        // 提取患者姓名 (Patient Name)
        XPN patientName = pid.getPatientName(0);
        String lastName = patientName.getFamilyName().encode();
        String firstName = patientName.getGivenName().getValue();
        // System.out.println("Patient Name: " + firstName + " " + lastName);

        Map<String,Object> userMap=new HashMap<>();
        userMap.put("name",lastName+firstName);
        userMap.put("identifier",medicalRecordNumber);

        try {
            ClientHolder.getSocketClient().writeAndFlush(new TextWebSocketFrame(objectMapper.writeValueAsString(userMap))).sync();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        for (ORU_R01_OBSERVATION oruR01Observation : oruMessage.getPATIENT_RESULT().getORDER_OBSERVATION().getOBSERVATIONAll()) {
            OBX o = oruR01Observation.getOBX();
            Varies roomNumber = o.getObservationValue(0);
            Type data1 = roomNumber.getData();
            String idCode = o.getObservationIdentifier().getIdentifier().getValue();
            // 心电图 1
            if (idCode.equals("131330")) {
                if(data1 instanceof NA) {
                    String[] arr=roomNumber.encode().split("\\^");
                    for(String ecgValue:arr){
                        ECG ecg=new ECG();
                        ecg.setEcg1(Integer.parseInt(ecgValue));
                        Context.queue.offer(ecg);
                    }
//                    System.out.println(System.currentTimeMillis());
               }
            } else if (idCode.equals("147842")) {
                //ecg 数值
                if (data1 instanceof NM) {
                    NM data = (NM) roomNumber.getData();
//                    System.out.println("ecg:"+data.getValue());
                    try {
                        ClientHolder.getSocketClient().writeAndFlush(new TextWebSocketFrame("{\"ecg\":"+data.getValue()+"}")).sync();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }else if(idCode.equals("150456")){
                // SPO2 数值
                NM data = (NM) roomNumber.getData();
                try {
                    ClientHolder.getSocketClient().writeAndFlush(new TextWebSocketFrame("{\"spo2\":"+data.getValue()+"}")).sync();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }else if(idCode.equals("150037")){
                // 收缩压
                NM data = (NM) roomNumber.getData();
                try {
                    ClientHolder.getSocketClient().writeAndFlush(new TextWebSocketFrame("{\"sbp\":"+data.getValue()+"}")).sync();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }else if(idCode.equals("150038")){
                // 收缩压
                NM data = (NM) roomNumber.getData();
                try {
                    ClientHolder.getSocketClient().writeAndFlush(new TextWebSocketFrame("{\"dbp\":"+data.getValue()+"}")).sync();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }else if(idCode.equals("151539")){
                // 收缩压
                NM data = (NM) roomNumber.getData();
                try {
                    ClientHolder.getSocketClient().writeAndFlush(new TextWebSocketFrame("{\"map\":"+data.getValue()+"}")).sync();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            } else if(idCode.equals("151578")){
                // 收缩压
                NM data = (NM) roomNumber.getData();
                try {
                    ClientHolder.getSocketClient().writeAndFlush(new TextWebSocketFrame("{\"resp\":"+data.getValue()+"}")).sync();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }else if (idCode.equals("150032")) {
                //Art 波形
                if(data1 instanceof NA) {
                    String[] arr=roomNumber.encode().split("\\^");
                    for(String art:arr){
                        scheduler.schedule(()->{
                            try {
                                ClientHolder.getSocketClient().writeAndFlush(new TextWebSocketFrame("{\"artWave\":"+art+"}")).sync();
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                        },delay,TimeUnit.NANOSECONDS);
                    }
                }
            } else if (idCode.equals("150452")) {
                //Pleth 波形
                if(data1 instanceof NA) {
                    String[] arr=roomNumber.encode().split("\\^");
                    for(String pleth:arr){
                        scheduler.schedule(()->{
                            try {
                                ClientHolder.getSocketClient().writeAndFlush(new TextWebSocketFrame("{\"plethWave\":"+pleth+"}")).sync();
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                        },delay,TimeUnit.NANOSECONDS);
                    }
                }
            } else if (idCode.equals("151780")) {
                 //RESP 波形 TODO:确认波形
                 if(data1 instanceof NA) {
                    String[] arr=roomNumber.encode().split("\\^");
                    for(String resp:arr){
                        scheduler.schedule(()->{
                            try {
                                ClientHolder.getSocketClient().writeAndFlush(new TextWebSocketFrame("{\"respWave\":"+resp+"}")).sync();
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                        },delay,TimeUnit.NANOSECONDS);
                    }
                }
            }
        }

        // 获取所有 OBX 段
        Terser terser = new Terser(message);
        String messageType = terser.get("/.MSH-9-1") + "_" + terser.get("/.MSH-9-2");
        String messageID = terser.get("/.MSH-10");
        String rawMessage = map.get("raw-message").toString();
        String sendingIP = map.get("SENDING_IP").toString();
        String sendingPort = map.get("SENDING_PORT").toString();

//        System.out.println(messageID +","+messageType);
//        System.out.println(SendIP);
//        System.out.println(SendPort);
//        System.out.println(rawMessage);

        Message message1 = null;
        try {
            message1 = message.generateACK();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return message1;
    }

    @Override
    public boolean canProcess(Message theMessage) {
        return true;
    }
}
